package com.csj.mvvm.ui.base

import android.app.Dialog
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.Window
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.csj.mvvm.R
import com.csj.mvvm.api.error.ErrorResult
import com.csj.mvvm.event.EventCode
import com.csj.mvvm.event.EventMessage
import com.csj.mvvm.utils.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.lang.reflect.ParameterizedType


abstract class BaseActivity<VM : BaseViewModel, VB : ViewDataBinding> : AppCompatActivity() {
    lateinit var mContext: FragmentActivity
    lateinit var vm: VM
    lateinit var v: VB

    private var loadingDialog: Dialog? = null
    private var builder: CustomDialog.Builder? = null
    var canCancel = true

    @Suppress("UNCHECKED_CAST")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initResources()

        if (needAnim()) {
            overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left)
        }

//        StatusBarUtil.immersive(this)
//        StatusBarUtil.darkMode(this)
        if (useStatusBar()) {
            // 设置为无标题栏
            supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
            // 沉浸状态栏
            //当FitsSystemWindows设置 true 时，会在屏幕最上方预留出状态栏高度的 padding
            StatusBarUtil2.setRootViewFitsSystemWindows(this, true)
            //设置状态栏透明
            StatusBarUtil2.setTranslucentStatus(this, !NightModeUtil.isNightMode(this))
        }

        //PS: type.actualTypeArguments[0]=BaseViewModel，type.actualTypeArguments[1]=ViewBinding
        val type = javaClass.genericSuperclass as ParameterizedType
        val clazz1 = type.actualTypeArguments[0] as Class<VM>
        vm = ViewModelProvider(this).get(clazz1)

        val clazz2 = type.actualTypeArguments[1] as Class<VB>
        val method = clazz2.getMethod("inflate", LayoutInflater::class.java)
        v = method.invoke(null, layoutInflater) as VB

        setContentView(v.root)

        v.lifecycleOwner = this

        mContext = this
        init()
        initData()
        initClick()
        initVM()
        LogUtil.d(getClassName())
    }

    /**
     * 防止系统字体影响到app的字体
     *
     * @return
     */
    open fun initResources(): Resources? {
//        val res: Resources = super.getResources()
//        val config = Configuration()
//        config.setToDefaults()
//        res.updateConfiguration(config, res.displayMetrics)
//        return res
        val config = resources.configuration
        return if (config.fontScale != 1f) {
//            config.fontScale = 1f
            config.setToDefaults()
            createConfigurationContext(config).resources
        } else {
            resources
        }

    }

    override fun onDestroy() {
        LogUtil.e(this@BaseActivity.toString() + " onDestroy")
        super.onDestroy()
        if (needAnim()) {
            overridePendingTransition(R.anim.in_from_left, R.anim.out_to_right)
        }
        EventBus.getDefault().unregister(this)
    }

    //事件传递
    @Subscribe
    fun onEventMainThread(msg: EventMessage) {
        handleEvent(msg)
    }

    open fun getClassName(): String? {
        val className = "BaseActivity"
        try {
            return javaClass.name
        } catch (e: Exception) {
        }
        return className
    }

    open fun needAnim(): Boolean {
        return true
    }

    open fun useStatusBar(): Boolean {
        return true
    }

    abstract fun initClick()

    abstract fun initData()

    //ViewModel的observe观察事件操作
    abstract fun initVM()

    private fun init() {
        EventBus.getDefault().register(this)
        //loading
        vm.isShowLoading.observe(this, Observer {
            if (it) showLoading() else dismissLoading()
        })
        //错误信息
        vm.errorData.observe(this, Observer {
            if (it.show) ToastUtil.showToast(it.errMsg)
            errorResult(it)
        })
    }

    fun showLoading(msg: String) {
        if (loadingDialog == null) {
            builder = CustomDialog.Builder(mContext).setCancelable(canCancel)
            loadingDialog = builder?.createLoading(msg)
        }
        builder?.startAnimation()
        loadingDialog?.show()
    }

    fun showLoading() {
        if (loadingDialog == null) {
            builder = CustomDialog.Builder(mContext).setCancelable(canCancel)
            loadingDialog = builder?.createLoading("")
        }
        builder?.startAnimation()
        loadingDialog?.show()
    }

    fun dismissLoading() {
        if (loadingDialog != null) {
            loadingDialog?.dismiss()
        }
    }

    /**
     * 消息、事件接收回调
     */
    open fun handleEvent(msg: EventMessage) {
        if (msg.code == EventCode.LOGIN_OUT) {
            finish()
        }
    }

    /**
     * 接口请求错误回调
     */
    open fun errorResult(errorResult: ErrorResult) {}

    /**
     * 控件自封装实现关闭页面的方法
     * 布局文件添加android:onclick="xxx"
     */
    open fun onClickFinish(v: View?) {
        finish()
    }

}